<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>双色球</title>
<!--    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>-->
    <!-- 本页面必须使用协商缓存 -->
    <meta http-equiv="Cache-Control" content="no-cache">
    <!-- 引入本地压缩版Vue3 -->
    <script src="vue.global.prod.js"></script>
    <style>
        /* 设置红球选区和蓝球选区并排显示,边框为圆角、半透明且大小一致  */
        .select {
            border: 1px solid #ccc;
            border-radius: 5px;
            padding: 5px;
            margin: 5px;
            width: 420px;
            height: 250px;
            overflow: auto;
            /* 设置浮动,使得两个选区并排显示 */
            float: left;
        }

        /* select里的第一个h3标签上边距为0 */
        .select h3:first-child {
            margin-top: 0;
        }

        /* 让checkbox不显示 */
        .select input {
            display: none;
        }

        /* 设置label的样式,有一个圆形外框,禁止被用户选中文本 */
        .select label {
            display: inline-block;
            width: 30px;
            height: 30px;
            line-height: 30px;
            text-align: center;
            border: 1px solid #ccc;
            border-radius: 50%;
            margin: 5px;
            user-select: none;
        }

        /* 设置被用户选中的input checkbox 对应的label的样式,背景色为红色 */
        .select.red label.red {
            background-color: red;
            color: #fff;
        }

        /* 设置蓝球选区的样式,背景色为蓝色 */
        .select.blue label.blue {
            background-color: blue;
            color: #fff;
        }
    </style>
</head>
<body>
<!-- 充当Vue的挂载容器 -->
<!-- 当在未采用构建流程的情况下使用 Vue 时，我们可以在挂载容器中直接书写根组件模板 -->
<div id="app">
    <h1>双色球</h1>
    <button @click="start = !start">{{ start ? "开始" : "返回简介" }}</button>
    <div v-if="start">
        <p>这是一个模拟双色球的前后端项目，前端负责收集用户输入，并呈现页面视图，后端负责处理中奖的业务逻辑</p>
        <p>前端技术栈：Vue3<br>
            后端技术栈：SpringBoot</p>
    </div>
    <!-- 红球选区和蓝球选区并排显示 -->
    <div v-else>
        <div class="select red">
            <h3>红球选区</h3>
            {{ redBalls }} <br>
            <template v-for="n in 33">
                <label :class="{red: redBalls.includes(n)}">
                    <input :value="n" type="checkbox" v-model="redBalls">
                    {{ n }}
                </label>
                <br v-if="n % 10 === 0">
            </template>
        </div>
        <div class="select blue">
            <h3>蓝球选区</h3>
            {{ blueBalls }} <br>
            <template v-for="n in 16">
                <label :class="{blue: blueBalls.includes(n)}">
                    <input :value="n" type="checkbox" v-model="blueBalls">
                    {{ n }}
                </label>
                <br v-if="n % 10 === 0">
            </template>
        </div>
        <div class="select">
            <h3>大奖信息</h3>
            <template v-for="info in maxTotalMoneyInfo">
                第{{info.count}}次抽奖,奖金{{info.money / 10000}}万元<br>
                中奖时间为：{{info.time}}<br>
                当时的净收益为：{{info.netMoney}}元<br>
                <!-- 分割线 -->
                <hr>
            </template>
        </div>
        <!-- 清空按钮 -->
        <div style="clear:both"> <!-- 元素被向下移动以清除左右浮动 -->
            <!-- 循环开始后，只有停止循环按钮能点击 -->
            <button :disabled="round" @click="clearBalls">清空选球</button>
            <button :disabled="round" @click="randomBalls">随机选号</button>
            <button :disabled="redBalls.length !== 6
            || blueBalls.length !== 1 || round" @click="dataPost">开奖
            </button>
            <button :disabled="round" @click="randomAndPost">随机选号并开奖</button>
            <!-- 循环控制按钮通过css样式与其他按钮隔开距离 -->
            <button :disabled="!round &&
            (redBalls.length !== 6 || blueBalls.length !== 1)" @click="roundPost"
                    style="margin-left: 5%">{{round ? "停止循环" : "循环开奖"}}
            </button>
            <button @click="roundRandomPost">{{round ? "停止循环" : "循环选号开奖"}}</button>
            <p v-if="winMoney !== null">
                中奖号码为：红球：{{winRedBalls}} 蓝球：{{winBlueBalls}} <br>
                您本次的中奖金额为：{{winMoney}}元 <br>
                总抽奖次数：{{count}} &nbsp总中奖次数：{{total}} &nbsp综合中奖率：{{total / count * 100}} % <br>
                总中奖金额：{{totalMoney}}元 &nbsp最高中奖金额：{{maxTotalMoney}}元 <br>
                总投入：{{count * 2}}元 &nbsp&nbsp净收益：{{totalMoney - (count * 2)}}元
                &nbsp&nbsp平均每张彩票的收益(花2元得几元)：{{totalMoney / count}}元<br>
                <button @click="clear">清空所有数据</button>
            </p>
        </div>
    </div>
</div>

<script>
    // 解构Vue3的API
    const {createApp, ref, watch} = Vue
    // 创建Vue实例
    const app = createApp({
        setup() {
            // 声明数据、方法
            let start = ref(true)
            let round = ref(false)
            let redBalls = ref([])
            let blueBalls = ref([])
            let winRedBalls = ref(null) // 中奖红球
            let winBlueBalls = ref(null)    // 中奖蓝球
            let winMoney = ref(null) // 中奖金额
            // 总抽奖次数
            let count = ref(0)
            // 中奖信息
            let total = ref(0)  // 总中奖次数
            let totalMoney = ref(0) // 总中奖金额
            let maxTotalMoney = ref(0) // 最高中奖金额
            const maxTotalMoneyInfo = ref([]) // 最高中奖金额的抽奖次数和时间列表

            // 清空选球数据
            function clearBalls() {
                redBalls.value = []
                blueBalls.value = []
            }

            // 清空所有数据
            function clear() {
                clearBalls()
                winRedBalls.value = null
                winBlueBalls.value = null
                winMoney.value = null
                total.value = 0
                totalMoney.value = 0
                count.value = 0
                maxTotalMoney.value = 0
            }

            // 随机选号
            function randomBalls() {
                clearBalls()
                const red = redBalls.value
                const blue = blueBalls.value
                while (red.length < 6) {
                    const n = Math.floor(Math.random() * 33) + 1
                    if (!red.includes(n)) {
                        red.push(n)
                    }
                }
                while (blue.length < 1) {
                    const n = Math.floor(Math.random() * 16) + 1
                    if (!blue.includes(n)) {
                        blue.push(n)
                    }
                }
            }

            // 提交 post请求，获取响应
            async function dataPost() {
                if (redBalls.value.length !== 6 || blueBalls.value.length !== 1) {
                    // 休眠1秒
                    await new Promise(resolve => setTimeout(resolve, 1000))
                    return
                }
                const req_data = {
                    red_balls: redBalls.value,
                    blue_balls: blueBalls.value
                }
                const res = await fetch('/lottery',
                    {
                        method: 'post',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        cache: 'no-store',
                        body: JSON.stringify(req_data)
                    }
                )
                const res_data = await res.json()
                winMoney.value = res_data.money
                winRedBalls.value = res_data.winLottery.red_balls.sort((a, b) => a - b)
                winBlueBalls.value = res_data.winLottery.blue_balls.sort((a, b) => a - b)
                count.value += 1
                if (res_data.money > 0) {
                    total.value += 1
                    totalMoney.value += res_data.money
                }
                if (res_data.money > maxTotalMoney.value) {
                    maxTotalMoney.value = res_data.money
                }
                if (res_data.money >= 1250000) {
                    maxTotalMoneyInfo.value.push({
                        money: res_data.money,
                        count: count.value,
                        time: new Date().toLocaleString(),
                        netMoney: totalMoney.value - (count.value * 2)
                    })
                }
            }

            function randomAndPost() {
                randomBalls()
                return dataPost()
            }

            function roundPost() {
                round.value = !round.value
                if (round.value) {
                    // 立即执行匿名异步函数
                    (async () => {
                        while (round.value) {
                            await dataPost()
                        }
                    })()
                }
            }

            function roundRandomPost() {
                round.value = !round.value
                if (round.value) {
                    // 立即执行匿名异步函数
                    (async () => {
                        while (round.value) {
                            await randomAndPost()
                        }
                    })()
                }
            }

            // 监听数据变化
            watch(redBalls, (newVal, oldVal) => {
                // 限制红球的个数
                if (newVal.length > 6) {
                    redBalls.value = oldVal
                    return
                }
                // 从小到大排序，确保数组始终有序
                redBalls.value = newVal.sort((a, b) => a - b);
            })
            watch(blueBalls, (newVal, oldVal) => {
                // 限制蓝球的个数
                if (newVal.length > 1) {
                    blueBalls.value = oldVal
                }
            })
            return {
                // 暴露给模板
                clearBalls,
                clear,
                dataPost,
                randomBalls,
                randomAndPost,
                roundPost,
                roundRandomPost,
                start,
                redBalls,
                blueBalls,
                winMoney,
                count,
                total,
                totalMoney,
                maxTotalMoney,
                winRedBalls,
                winBlueBalls,
                round,
                maxTotalMoneyInfo
            }
        }
    })
    // 挂载
    app.mount('#app')
</script>

</body>
</html>